Dividing by zero with SAS

32

dividing by zero with SAS

Whether you are a strong believer in the power of dividing by zero, agnostic, undecided, a supporter, denier or anything in between and beyond, this blog post will bring all to a common denominator.

History of injustice

For how many years have you been told that you cannot divide by zero, that dividing by zero is not possible, not allowed, prohibited? Let me guess: it’s your age minus 7 (± 2).

But have you ever been bothered by that unfair restriction? Think about it: all other numbers get to be divisors. All of them, including positive, negative, rational, even irrational and imaginary. Why such an injustice and inequality before the Law of Math?

We have our favorites like π, and prime members (I mean numbers), but zero is the bottom of the barrel, the lowest of the low, a pariah, an outcast, an untouchable when it comes to dividing by. It does not even have a sign in front of it. Well, it’s legal to have, but it’s meaningless.

And that’s not all. Besides not being allowed in a denominator, zeros are literally discriminated against beyond belief. How else could you characterize the fact that zeros are declared as pathological liars as their innocent value is equated to FALSE in logical expressions, while all other more privileged numbers represent TRUE, even the negative and irrational ones!

I also recommend: Dividing by zero with SAS - myths and realities

Extraordinary qualities of zeros

Despite their literal zero value, their informational value and qualities are not less than, and in many cases significantly surpass those of their siblings. In a sense, zero is a proverbial center of the universe, as all the other numbers dislocated around it as planets around the sun. It is not coincidental that zeros are denoted as circles, which makes them forerunners and likely ancestors of the glorified π.

Speaking of π, what is all the buzz around it? It’s irrational. It’s inferior to 0: it takes two π’s to just draw a single zero (remember O=2πR?). Besides, zeros are not just well rounded, they are perfectly rounded.

Privacy protection experts and GDPR enthusiasts love zeros. While other small numbers are required to be suppressed in published demographic reports, zeros may be shown prominently and proudly as they disclose no one’s personally identifiable information (PII).

No number rivals zero. Zeros are perfect numerators and equalizers. If you divide zero by any non-zero member of the digital community, the result will always be zero. Always, regardless of the status of that member. And yes, zeros are perfect common denominators, despite being prohibited from that role for centuries.

Zeros are the most digitally neutral and infinitely tolerant creatures. What other number has tolerated for so long such abuse and discrimination!

Enough is enough!

Dividing by zero opens new horizons

Can you imagine what new opportunities will arise if we break that centuries-old tradition and allow dividing by zero? What new horizons will open! What new breakthroughs and discoveries can be made!

With no more prejudice and prohibition of the division by zero, we can prove virtually anything we wish. For example, here is a well-known short 5-step mathematical proof of “4=5”:

1)   4 – 4 = 10 – 10
2)   22 – 22 = 5·(2 – 2)
3)   (2 + 2)·(2 – 2) = 5·(2 – 2) /* here we divide both parts by (2 – 2), that is by 0 */
4)   (2 + 2) = 5
5)   4 = 5

Let’s make the next logical step. If dividing by zero can make any wish a reality, then producing a number of our choosing by dividing a given number by zero scientifically proves that division by zero is not only legitimate, but also feasible and practical.

As you will see below, division by zero is not that easy, but with the power of SAS, the power to know and the powers of curiosity, imagination and perseverance nothing is impossible.

Division by zero - SAS implementation

Consider the following use case. Say you think of a “secret” number, write it on a piece of paper and put in a “secret” box. Now, you take any number and divide it by zero. If the produced result – the quotient – is equal to your secret number, wouldn’t it effectively demonstrate the practicality and magic power of dividing by zero?

Here is how you can do it in SAS. A relatively “simple”, yet powerful SAS macro %DIV_BY_0 takes a single number as a numerator parameter, divides it by zero and returns the result equal to the one that is “hidden” in your “secret” box. It is the ultimate, pure artificial intelligence, beyond your wildest imagination.

All you need to do is to run this code:

 
data MY_SECRET_BOX;        /* you can use any dataset name here */
   MY_SECRET_NUMBER = 777; /* you can use any variable name here and assign any number to it */
run;
 
%macro DIV_BY_0(numerator);
 
   %if %sysevalf(&numerator=0) %then %do; %put 0:0=1; %return; %end;
   %else %let putn=&sysmacroname; 
   %let %sysfunc(putn(%substr(&putn,%length(&putn)),words.))=
   %sysevalf((&numerator/%sysfunc(constant(pi)))**&sysrc);  
   %let a=com; %let null=; %let nu11=%length(null); 
   %let com=*= This is going to be an awesome blast! ;
   %let %substr(&a,&zero,&zero)=*Close your eyes and open your mind, then;
   %let imagine = "large number like 71698486658278467069846772 Bytes divided by 0";
   %let O=%scan(%quote(&c),&zero+&nu11); 
   %let l=%scan(%quote(&c),&zero);
   %let _=%substr(%scan(&imagine,&zero+&nu11),&zero,&nu11);
   %let %substr(&a,&zero,&zero)%scan(&&&a,&nu11+&nu11-&zero)=%scan(&&&a,-&zero,!b)_;
   %do i=&zero %to %length(%scan(&imagine,&nu11)) %by &zero+&zero;
   %let null=&null%sysfunc(&_(%substr(%scan(&imagine,&nu11),&i,&zero+&zero))); %end;
   %if &zero %then %let _0=%scan(&null,&zero+&zero); %else;
   %if &nu11 %then %let _O=%scan(&null,&zero);
   %if %qsysfunc(&O(_&can)) %then %if %sysfunc(&_0(&zero)) %then %put; %else %put;
   %put &numerator:0=%sysfunc(&_O(&zero,&zero));
   %if %sysfunc(&l(&zero)) %then;
 
%mend DIV_BY_0;
 
%DIV_BY_0(55); /* parameter may be of any numeric value */

When you run this code, it will produce in the SAS LOG your secret number:

55:0=777

How is that possible without the magic of dividing by zero? Note that the %DIV_BY_0 macro has no knowledge of your dataset name, nor the variable name holding your secret number value to say nothing about your secret number itself.

That essentially proves that dividing by zero can practically solve any imaginary problem and make any wish or dream come true. Don’t you agree?

There is one limitation though. We had to make this sacrifice for the sake of numeric social justice. If you invoke the macro with the parameter of 0 value, it will return 0:0=1 – not your secret number - to make it consistent with the rest of non-zero numbers (no more exceptions!): “any number, except zero, divided by itself is 1”.

Challenge

Can you crack this code and explain how it does it? I encourage you to check it out and make sure it works as intended. Please share your thoughts and emotions in the Comments section below.

Disclosure

This SAS code contains no cookies, no artificial sweeteners, no saturated fats, no psychotropic drugs, no illicit substances or other ingredients detrimental to your health and integrity, and no political or religious statements. It does not collect, distribute or sell your personal data, in full compliance with FERPA, HIPPA, GDPR and other privacy laws and regulations. It is provided “as is” without warranty and is free to use on any legal SAS installation. The whole purpose of this blog post and the accompanied SAS programming implementation is to entertain you while highlighting the power of SAS and human intelligence, and to fool around in the spirit of the date of this publication.

Let's get serious: Dividing by zero with SAS - myths and realities
Share

About Author

Leonid Batkhan

Leonid Batkhan is a long-time SAS consultant and blogger. Currently, he is a Lead Applications Developer at F.N.B. Corporation. He holds a Ph.D. in Computer Science and Automatic Control Systems and has been a SAS user for more than 25 years. From 1995 to 2021 he worked as a Data Management and Business Intelligence consultant at SAS Institute. During his career, Leonid has successfully implemented dozens of SAS applications and projects in various industries. All posts by Leonid Batkhan >>>

32 Comments

  1. Benjamin Ben-Baruch on

    For me, a useful application of this neat "trick" would be to eliminate error messages in code that accidentally divides by 0 in some (or even all) cases. Currently (as mentioned above by Steve Sconfienza) there is a "work-around" for this but it is "clumsy":
    IF var1 ~= 0 THEN Var2 / Var1 ; ELSE . ;
    At some point when I have more time to play, I would like to see if I could revise this code so that whenever division by 0 occurs it results in a NULL or MISSING value. Unfortunately I don't have this luxury having just returned from a vacation. Alternatively, if someone beats me to this solution, I would be appreciative and I would name my macro and/or code after her/him.

    • Leonid Batkhan

      Benjamin, for this humble and practical purpose, you can shield yourself from post-vacation stress and the ERRORs of accidentally dividing by zero by using SAS' divide() function. It produces special missing values (.I for ∞, .M for -∞) for zero denominator and no erros. Run this code to see what it does:

      data _null_;
         x = divide(5,0);
         if x=.I then put x=;
         if missing(x) then put x=;
      
         n=-5; d=0;
         x=divide(n,d);
         if x=.M then put x=;
         if missing(x) then put x=;
      run;
      

  2. Benjamin Ben-Baruch on

    Your conclusion that 4=5 is old hat. George Orwell provided the socio-economic-political proof of this in 1984 but he phrased it differently:
    2+2=5

    • Leonid Batkhan

      Hi Benjamin, it's not my conclusion. I am just using this well-known "proof" by un-concealing its "prohibited" division by zero as a transitional step to the point of this blog post: "If dividing by zero can make any wish a reality, then producing a number of our choosing by dividing a given number by zero scientifically proves that division by zero is not only legitimate, but also feasible and practical."

      • Benjamin Ben-Baruch on

        I understood that.
        I was always taught that division by zero was undefined -- not that it was not allowed or impossible. You created one possible definition (or set of definitions) for dividing by zero while also providing a neat coding "trick" and useful and provocative thought exercise.

        In a sense, you provided an example of Orwell's commentary on authoritarianism: One feasible and practical manifestation of the political power to control the definition of "truth" or or of facts is the power to manipulate language and the perceptions of truth on a mass scale.

        Mathematicians et.. al. "play" these speculative "games" all the time because within mathematics and related fields this is how progress is made. Nevertheless, in most "applied mathematics" we continue to leave division by zero undefined -- or we take the practical step of defining the result of dividing by 0 "missing" or "null" because while it may be a wonderful thought exercise to imagine building a bridge to the sky, for most applied purposes we want to build bridges that don't fall down. In a sense, this is no different from using Newton's law of gravity. We know that Newton's theory of gravity is simply wrong. However applying it works pretty well as long as we are on the planet earth.

        When it comes to politics, however, Orwell's warning stands. And when it comes to engineering things that will be built on earth, Newton's theory is still useful.

  3. Aad van Strien on

    Though I'm using SAS for some 40+ years now, my first attempt to run this program just failed. Incredibly. It let me wonder "how come"?
    The simple answer is, I submitted the program to an EBCDIC environment, not an ASCII one.
    Anyhow, nice hidden coding to retrieve the content of the last dataset. Thanks or the challenge!

    • Leonid Batkhan

      Thank you, Aad, for your comment. I am glad that initial failure did not stop you and you still managed to solve this challenge. Indeed, this macro heavily relies on ASCII codes, and I erroneously assumed that no one uses IBM mainframes and AS/400s anymore. The optimal solution is to stop using them immediately. Of course, I could have augmented the macro with a logic accounting for whether SAS runs on ASCII or EBCDIC (e.g. byte(78)='N' for ASCII, byte(78)='+' for EBCDIC), but that would have been too backward-looking solution...

  4. Steve Sconfienza on

    Yes, I was able to parse-out the various fragments of words and functions to OPEN the _LAST_ dataset, FETCH the observation, and then CLOSE the dataset: very creative, and having that really big number be a text string was very elegant.

    Very good post.

  5. Steve Sconfienza on

    Am I imagining things or have you set &zero equal to 1? Isn't that cheating?

    Also, there _are_ work-arounds to the zero-in-the-numerator problem, such as testing for a 0 argument and using a different variable with a default value as the numerator in that cheat: a few more lines of code.

    One _might_ think that if something were to be divided zero times it would be whole, while dividing it one time would leave two pieces, but then dividing it two times would be four pieces, and dividing it fur times would be _Eight_ pieces (just like a pizza, fresh from the oven, from the nearest wood-fired pizzeria. . . . but I digress). Somehow, in ZERO losing its rightful place in the pantheon of numbers, we do not seem to do our math correctly: just watch -- and count -- the next time you go for a snack.

    • Leonid Batkhan

      Steve, thank you for your comments.
      1. &zero=1 is not cheating, as zero here is just a macro variable name, it can have any value including 1.
      2. The zero-in-the-numerator is not a problem, but intentionally made "sacrifice" to limit our mind-reading capability to satisfy the rule "any number divided by itself is equal to 1".
      3. It is a thought-provoking take on the "dividing" semantics. Yes, if "to divide" means "to split" or "to halve" then you are absolutely correct. Very interesting observation.

      But I digress. Have you figured out how that %div_by_0 macro gets that "secret number" from the preceding data step?

  6. Leonard Seitz on

    Zero is also denied its proper role in 12 hour clocks and keyboards:
    "0" should be on the tops of 12 hour clocks; at least noon should be 12 a.m.; then 1:00 p.m. would be one hour after noon. SAS times, being seconds from a time long ago, don't have a problem.
    And, why is the keyboard zero on the far right instead of left of one.

    • Leonid Batkhan

      Good points, Leonard! Yes, 12 on the clock should be combined with 0. Then noon should be 0:00 pm. I also agree with you on the incorrect location of the 0 key on a computer keyboard. Obviously, 0 after 9 is the wrong place (we all know that 9 is followed by 10, not 0), 0 should be on the very left before 1. This is also true for the phone keyboards and TV remote controls. It just re-affirms my point that zeros are pushed around …

  7. Excellent! Very fun read. Takes me back to the after-school TV "Schoolhouse Rock" days with the clever "Zero My Hero" cartoon.

  8. Thank you, Leonid, for the reminder number Zero - it is nice to have the question pondered once in a while:

    "But have you ever been bothered by that unfair restriction?"

    - to dream of worlds where dividing by zero is consistent joy with beautiful consequences. =)

  9. Peter Lancashire on

    Here in Europe we have a floor zero in buildings; it's called the ground floor. The first floor is the next one up. That's the digital future. Counting from one as in the USA is so old school.

    • Leonid Batkhan

      Hi Peter, thank you for your input. Indeed, USA differs from Europe when it comes to counting floors in buildings. We do, however, have "ground floor" - we call it basement. Despite our differences, I think we all can agree on counting days of months starting from 0 instead of 1, at least for the month of April. That would make April Fool's day fall on April 0 which will make it more memorable.

  10. (2 + 2)·(2 – 2) = 5·(2 – 2)
    should we just ignore the order of operations here?
    because evaluating the parenthesis results in:
    4 x 0 = 5 x 0
    0 = 0

    • Leonid Batkhan

      We do not ignore the order of operations here. However, (2 + 2)·(2 – 2) = 5·(2 – 2) could be processed in different ways. For the purpose of this blog, we decided to divide both parts by (2-2) before evaluating the parenthesis which leads to (2 + 2) = 5.

  11. Tamas Tukszar on

    Even though 4 can equal 5 today, I like how you defended zero, the hero of the article!
    Just recalled another restriction of use of zero: in the world of clinical trials where I work, there is no day 0, day 1 comes after day -1. I miss it sometimes... 🙂

  12. This is fun. I remember learning the "0 = 1 proof" (as I learned it) during high school.

    Clever use of GETVARN.FETCH! I'd do a longer write-up if April Fool's was treated as a federal holiday 😉

Leave A Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to Top